#ifndef ZOO_H
#define ZOO_H
#include <string>
#include <vector>
#include <iostream>
using namespace std;
class Money
{
private:
	double totalincome;
public:
	Money();
	Money(const double & m);
	Money operator+(const double& m);
	Money operator-(const double& m);
	Money operator+(const Money&other);
	Money operator-(const Money&other);
	double getmoney();
	~Money() {};
};
class AnimalFood
{
private:
	string type;
	int amount;
public:
	AnimalFood();
	AnimalFood(const string nameoftype, const int eamount);
	void settype(const string nameoftype);
	void setamount(const int eamount);
	void reduceamount(int r);
	string gettype();
	int getamount();
	~AnimalFood() {};
};
class AnimalEnclosure
{
private:
	double dirtlevel;
	bool curstatus;
public:
	AnimalEnclosure();
	void adddirlevel(const double m);
	bool isclosed();
	void open();
	void close();
	void resetdir();
	double getdirtlevel();
	bool getcurstatus();
	~AnimalEnclosure() {};
};
class Animal
{
protected:
	double weight;
	double eatenfoodnum;
public:
	Animal();
	Animal(const double &w);
	virtual void eat(AnimalFood& food) {};
	double getfoodeaten();
	void resetfoodeaten();
	virtual ~Animal() {};
};
class Elephant :public Animal
{
private:
	double trunklength;
public:
	Elephant() ;
	Elephant(const double &w,const double &t);
	void eat(AnimalFood& food)override;
};
class Giraffe :public Animal
{
private:
	double necklength;
public:
	Giraffe();
	Giraffe(const double &w,const double &n);
	void eat(AnimalFood& food)override;
};
class Monkey :public Animal
{
private:
	double armlength;
public:
	Monkey();
	Monkey(const double &w, const double &a);
	void eat(AnimalFood& food)override;
};
class Person
{
protected:
	string name;
	int age;
public:
	Person();
	Person(const string ownname,const int ownage);
	virtual ~Person() {};
};
class ZooKeeper :public Person
{
private:
	int totalcleaningday;
public:
	ZooKeeper();
	ZooKeeper(const string ownname, const int ownage);
	void addtotalcleaningday();
	int gettotalcleaningday();
	~ZooKeeper() {};
};
class FoodSeller :public Person
{
private:
	vector<AnimalFood>sellfood;
	Money foodincome;
public:
	FoodSeller() {}
	FoodSeller(string ownname,int ownage);
	double getincomeoffood();
	bool avail(const string& n);
	bool Sellfood(const string &n,const int &quantity,const double &payment);
	~FoodSeller() {};
};
class Visitor :public Person
{
private:
	int passid;
public:
	Visitor();
	Visitor(const string& n, const int& a, const int& p);
	~Visitor() {};
};
class Child :public Visitor
{
private:
	vector<AnimalFood>childhas;
public:
	Child() {};
	Child(const string& n, const int& a, const int& p);
	void addfood(AnimalFood& add);
	void feed(Animal *a);
	~Child() {};
};
class Adult:public Visitor
{
private:
	double ownmoney;
	int childnum;
public:
	vector<Child>accompany;
	Adult() {};
	Adult(const string& n, const int& a, const int& p,const int &cn);
	void payforpass(Money& income);
	void payforfood(FoodSeller &f);
	~Adult() {};
};
class Zoo
{
private:
	vector<Animal*>animals;
	vector<AnimalEnclosure>animalenclosures;
	ZooKeeper zookeeper;
	FoodSeller foodseller;
	Money income;
	int totalrunday;
	int totalnumofadult;
	int totalnumofchild;
	int animalenclosureclose[3];
public:
	Zoo();
	void runaday();
	void run();
	~Zoo();
};
#endif
